/*  tBookShelf: TextPlugin
    (C) 2007  TvN (Volodymyr Tarasenko), e-mail: tvntsr@yahoo.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef LBOOK_TEXT_PLUGIN_HPP
#define LBOOK_TEXT_PLUGIN_HPP

#include "Utils/DebugStream.hpp"
#include "TextPlugin/TextReader.hpp"


#define TRACE                              \
do{                                        \
    dout << "Function "                    \
         << __FUNCTION__                   \
         << " called"                      \
         << std::endl;                     \
}while(0)


#define PLUGIN_PARSER_NAME "TextPluginParser"
#define PLUGIN_PARSER_VER  "0.0.1"
#define PLUGIN_INTERF_VER  "0.0.1"

#define Hl_OK  1
#define Hl_BAD 0

#ifndef DEFAULT_MAX_PAGE_CACHE
#define DEFAULT_MAX_PAGE_CACHE 10
#endif

struct HlPageS;

struct HlDocumentS
{
    HlDocInfo    doc_info;
    HlLayoutInfo layout_info;

    TextReader   text_reader;

    HlDocumentS(const char*   file_name, 
                const HlRect& screenRect,
                int           lang)
        : text_reader()
    {
        memset(&doc_info,    0, sizeof(doc_info));
        memset(&layout_info, 0, sizeof(layout_info));

        doc_info.fileName = strdup(file_name); // :FIXME: check return

        doc_info.lang = lang;
        //HlDocTypeUnknow, HlDocTypeFluidLayout, HlDocTypeFixLayout
        // doc_info.type = HlDocTypeFixLayout;
//         doc_info.type = HlDocTypeFluidLayout;
        doc_info.type = HlDocTypeUnknow;

        layout_info.layoutWidth = layout_info.screenWidth = screenRect.w;
        layout_info.layoutHeight= layout_info.screenHeight= screenRect.h;

        layout_info.fontSize = 14;
        layout_info.interwordSpace = 4;
        layout_info.interlineSpace = 10;
    }

    ~HlDocumentS()
    {    }

    void setDocType(const std::string& name)
    {
        if (name == "FixLayout")
        {
            doc_info.type = HlDocTypeFixLayout;
        }
        else if (name == "FluidLayout")
        {
            doc_info.type = HlDocTypeFluidLayout;
        }
        else if (name == "Unknow")
        {
            doc_info.type = HlDocTypeUnknow;
        }
        // leave untouched 
    }

    int setDocInfo(const HlDocInfo *info)
    {
        if ((info)&&(info != &doc_info))
            memcpy(&doc_info, info, sizeof(doc_info));

        return Hl_OK;
    }

    int getDocInfo(HlDocInfo *info) const
    {
        if ((info)&&(info != &doc_info))
            memcpy(info, &doc_info, sizeof(doc_info));

        return Hl_OK;
    }

    int setLang(int lang)
    {
        int old = doc_info.lang;

        doc_info.lang = lang;

        return old;
    }

    int getLayout(HlLayoutInfo* info) const
    {
        if ((info)&&(info != &layout_info))
            memcpy((void*)info, (void*)&layout_info, sizeof(layout_info));

        return Hl_OK;
    }

    int setLayout(const HlLayoutInfo* info)
    {
        if ((info)&&(info != &layout_info))
            memcpy((void*)&layout_info, (void*)info, sizeof(layout_info));

        return Hl_OK;
    }

    HlPageS* getPage(int pageNo);
};



struct HlPageS
{
    HlPageInfoS    page_info;
    HlDocument*    document;

private:
    friend struct HlDocumentS;

    HlPageS(HlDocumentS* doc, int page_num)
        :document(doc)
    {
        memset(&page_info, 0, sizeof (page_info));

        page_info.pageNo = page_num;
        page_info.width  = doc->layout_info.screenWidth;
        page_info.height = doc->layout_info.screenHeight;

        page_info.contentRect.x = 0;
        page_info.contentRect.y = 0;
        
        page_info.contentRect.w = page_info.width;
        page_info.contentRect.h = page_info.height;
    }

public:

    ~HlPageS()
    {    }

    int setPageInfo(const HlPageInfo *info)
    {
        if ((info)&&(info != &page_info))
        {
            memcpy(&page_info, info, sizeof(page_info));
        }

        return Hl_OK;
    }

    int getPageInfo(HlPageInfo *info) const
    {
        if ((info)&&(info != &page_info))
        {
            memcpy(info, &page_info, sizeof(page_info));
        }

        return Hl_OK;
    }

    int getPageText(unsigned char* text, int len);

    PageOrientation getOrientation() const
    {
        switch(page_info.rotation)
        {
            case HlDocRotate_0:
            case HlDocRotate_180:
                return Portrait;
            default:
                return Landscape;
        }

        return Portrait;
    }

    int getPageNum() const
    {
        return page_info.pageNo;
    }
};

struct HlOutlineS
{
    HlOutline*         parentOutline;
    std::vector<HlOutline*> childOutline;
    HlDocument*        document;
    int                childNum;

    HlOutlineS()
        : parentOutline(0), document(0), childNum(-1)
    {
    }
};

struct HlSegmentS
{
};

#endif // LBOOK_TEXT_PLUGIN_HPP
